import re
from contextlib import nullcontext
from datetime import datetime
from sqlite3 import IntegrityError

from flask import Blueprint, request, jsonify, render_template, session, redirect, url_for
from sqlalchemy.sql.elements import or_

from Blueprint import student
from Models import Student, db, Classes, Teacher, Course

admin_bp = Blueprint('admin',__name__,url_prefix='/admin')
def validate_telephone(telephone):
    return re.match(r'^1[3-9]\d{9}$', telephone) is not None



# 钩子函数，当执行视图函数前先判断当前是否登录
@admin_bp.before_request
def check_login():
    # 检查用户是否登录
    if session.get('user_type') !='admin':
        return redirect(url_for('login'))
    if session.get('username') is None:
        return redirect(url_for('login'))  # 使用正确的登录端点


# 写路由
@admin_bp.route('/')
def manage_student():
    print(session.get('username'))
    student_list = Student.query.all()
    classes_list = Classes.query.all()
    return render_template('admin/student_admin.html', student_list=student_list, classes_list=classes_list)

@admin_bp.route('/add', methods=['POST'])
def add_student():
    data = request.get_json()
    # 验证必填字段
    required_fields = ['student_no', 'username', 'age', 'class_id', 'status', 'password']
    for field in required_fields:
        if field not in data or not data[field]:
            return jsonify({
                'success': False,
                'message': f'缺少必填字段: {field}'
            }), 400

    # 验证学号唯一性
    if Student.query.filter_by(student_no=data['student_no']).first():
        return jsonify({
            'success': False,
            'message': '学号已存在',
            'error': 'student_no_exists'
        }), 400



    # 验证手机号（存在时）
    if 'telephone' in data and data['telephone']:
        if not validate_telephone(data['telephone']):
            return jsonify({
                'success': False,
                'message': '手机号码格式不正确'
            }), 400

    # 创建学生对象
    new_student = Student(
        student_no=data['student_no'],
        username=data['username'],
        age=data['age'],
        class_id=data['class_id'],
        status=data['status'],
        telephone=data.get('telephone'),
        gender=data.get('gender'),
        major=data.get('major'),
        address=data.get('address'),
        password=data['password']
    )

    # 保存到数据库
    try:
        db.session.add(new_student)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': '数据库操作失败'
        }), 500

    return jsonify({
        'success': True,
        'message': '学生添加成功'
    }), 201
# 获取学生信息（用于编辑）
@admin_bp.route('/get/<int:id>', methods=['GET'])
def get_student(id):
    student = Student.query.get_or_404(id)
    return jsonify({
        'success': True,
        'data': {
            'studentNo': student.student_no,
            'password': student.password,
            'username': student.username,
            'age': student.age,
            'gender': student.gender,
            'telephone': student.telephone,
            'address': student.address,
            'classId':str(student.class_id),
            'major': student.major,
            'status': student.status
        }
    })
# 更新学生信息
@admin_bp.route('/update/<int:id>', methods=['PUT'])
def update_student(id):
    student = Student.query.get_or_404(id)
    data = request.get_json()

    # 验证必填字段（更新时至少需要学号、姓名等核心字段，可根据需求调整）
    required_fields = ['student_no', 'username', 'class_id', 'status']
    for field in required_fields:
        if not data.get(field):
            return jsonify({'success': False, 'message': f'缺少必填字段: {field}'}), 400

    # 验证学号唯一性（如果学号被修改）
    if data['student_no'] != student.student_no:
        if Student.query.filter_by(student_no=data['student_no']).first():
            return jsonify({
                'success': False,
                'message': '学号已存在',
                'error': 'student_no_exists'
            }), 400

    # 更新字段
    student.student_no = data['student_no']
    student.username = data['username']
    student.age = int(data.get('age', student.age))  # 可选字段，默认使用原值
    student.class_id = int(data['class_id'])
    student.status = data['status']
    student.telephone = data.get('telephone', student.telephone)
    student.gender = data.get('gender', student.gender)
    student.major = data.get('major', student.major)
    student.address = data.get('address', student.address)

    # 更新密码（如果有传入新密码）
    if data.get('password'):
        student.password = data['password']

    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': '数据库更新失败'}), 500

    return jsonify({
        'success': True,
        'message': '学生信息更新成功'
    }), 200
@admin_bp.route('/delete/<int:id>', methods=['DELETE'])
def delete_student(id):
    try:
        # 查询学生是否存在
        student = Student.query.get_or_404(id)

        # 删除学生
        db.session.delete(student)
        db.session.commit()

        return jsonify({
            'success': True,
            'message': '学生删除成功'
        }), 200

    except Exception as e:
        db.session.rollback()  # 回滚事务
        return jsonify({
            'success': False,
            'message': '删除失败：' + str(e)
        }), 500
@admin_bp.route('/search', methods=['GET', 'POST'])
def search_students():
    keyword = request.args.get('keyword', '').strip()
    # 构建查询
    query = Student.query
    if keyword:
        query = query.filter(
            (Student.student_no.ilike(f'%{keyword}%')) |
            (Student.username.ilike(f'%{keyword}%'))
        )
    # 获取所有匹配结果（不分页）
    students = query.all()
    return render_template('admin/student_admin.html',
                           student_list=students,
                           search_keyword=keyword)

@admin_bp.route('/teacher_admin', methods=['GET', 'POST'])
def teacher_admin():
    teachers = Teacher.query.all()
    return render_template('admin/teacher_admin.html',teachers=teachers)

@admin_bp.route('/add_teacher', methods=['POST'])
def add_teacher():
    """新增教师"""
    data = request.get_json()
    if not data:
        return jsonify({
            'success': False,
            'message': '请求数据为空'
        }), 400

    # 数据验证
    required_fields = ['username', 'teacher_no', 'title', 'department']
    for field in required_fields:
        if not data.get(field):
            return jsonify({
                'success': False,
                'message': f'缺少必填字段: {field}'
            }), 400

    # 验证工号格式
    if not data['teacher_no'].startswith('T') or not data['teacher_no'][1:].isdigit():
        return jsonify({
            'success': False,
            'message': '工号格式错误，需以T开头并跟随数字'
        }), 400

    # 处理入职日期
    hire_date = None
    if data.get('hire_date'):
        try:
            hire_date = datetime.strptime(data['hire_date'], '%Y-%m-%d').date()
        except ValueError:
            return jsonify({
                'success': False,
                'message': '入职日期格式错误，正确格式: YYYY-MM-DD'
            }), 400

    # 检查工号是否已存在
    if Teacher.query.filter_by(teacher_no=data['teacher_no']).first():
        return jsonify({
            'success': False,
            'message': '该工号已被使用',
            'error': 'teacher_no_exists'
        }), 400

    # 检查用户名是否已存在
    if Teacher.query.filter_by(username=data['username']).first():
        return jsonify({
            'success': False,
            'message': '该用户名已被使用'
        }), 400

    # 处理密码（如果未提供，则生成随机密码）
    password = data.get('password')


    # 创建教师对象
    new_teacher = Teacher(
        username=data['username'],
        password=password,
        teacher_no=data['teacher_no'],
        title=data['title'],
        department=data['department'],
        hire_date=hire_date,
        email=data.get('email'),
        telephone=data.get('telephone'),
        address=data.get('address')
    )
    db.session.add(new_teacher)
    db.session.commit()
    return jsonify({
            'success': True,
            'message': '教师添加成功',

        }), 201


@admin_bp.route('/teacher/<int:teacher_id>', methods=['GET'])
def get_teacher(teacher_id):
    teacher = Teacher.query.get(teacher_id)
    if teacher.hire_date != None:
        teacher.hire_date=teacher.hire_date.strftime('%Y-%m-%d')
    return jsonify({
        'success': True,
        'data': {
            'id': teacher.id,
            'teacher_no': teacher.teacher_no,
            'password': teacher.password,
            'username': teacher.username,
            'title': teacher.title,
            'department': teacher.department,
            'hire_date':teacher.hire_date ,
            'email': teacher.email,
            'telephone': teacher.telephone,
            'address': teacher.address
        }
    }), 200

@admin_bp.route('/teacher/<int:teacher_id>', methods=['PUT'])
def update_teacher(teacher_id):
    teacher = Teacher.query.get(teacher_id)
    if not teacher:
        return jsonify({'success': False, 'message': '教师不存在'}), 404
    data = request.get_json()
    if not data:
        return jsonify({'success': False, 'message': '请求数据为空'}), 400
    # 数据验证
    errors = {}
    if 'password' in data and data['password'] and len(data['password']) < 6:
        errors['password'] = '密码长度至少6位'
    if errors:
        return jsonify({'success': False, 'message': '验证失败', 'errors': errors}), 400
    # 更新教师信息
    teacher.username = data['username']
    teacher.title = data['title']
    teacher.department = data['department']
    teacher.hire_date = datetime.strptime(data['hire_date'], '%Y-%m-%d').date()
    teacher.email = data['email']
    teacher.telephone = data['telephone']
    teacher.address = data['address']
    teacher.password =data['password']
    db.session.commit()
    return jsonify({'success': True, 'message': '更新成功'}), 200


# 删除教师
@admin_bp.route('/teacher/<int:teacher_id>', methods=['DELETE'])
def delete_teacher(teacher_id):
    teacher = Teacher.query.get(teacher_id)
    if not teacher:
        return jsonify({'success': False, 'message': '教师不存在'}), 404
    try:
        db.session.delete(teacher)
        db.session.commit()
        return jsonify({'success': True, 'message': '删除成功'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': '删除失败', 'error': str(e)}), 500


@admin_bp.route('teacher_search', methods=['GET'])
def get_teacher_search():
    # 获取搜索关键词（从前台表单）
    keyword = request.args.get('keyword', '').strip()
    query = Teacher.query
    if keyword:
        # 搜索工号或姓名中包含关键词的记录
        search_term = f'%{keyword}%'
        query = query.filter(
            (Teacher.teacher_no.ilike(search_term)) |
            (Teacher.username.ilike(search_term))
        )
        # 执行查询并获取所有结果
        teachers = query.all()
        # 渲染HTML模板并返回
        return render_template('admin/teacher_admin.html',
                               teachers=teachers,
                               search_keyword=keyword)


# 系统配置
@admin_bp.route('system',methods=['GET'])
def get_system():
    return render_template('admin/system.html')


# 退出登录选项
@admin_bp.route('logout', methods=['POST'])
def logout():
        try:
            # 清除服务器端会话（如使用session）
            session.clear()
            # 其他操作：如使Token失效（适用于JWT场景）
            # 例如：将Token加入黑名单（需配合Redis等缓存）

            return jsonify({
                'success': True,
                'message': '退出登录成功'
            })
        except Exception as e:
            return jsonify({
                'success': False,
                'message': '退出登录失败，请稍后重试'
            }), 500


@admin_bp.route('course')
def course():
    courses = Course.query.all()
    return render_template('admin/course_admin.html',courses=courses)


# 新增课程
@admin_bp.route('/course/add_course', methods=['POST'])
def add_course():
    data = request.form
    # print(data)
    # 验证必填字段
    required_fields = ['courseCode', 'courseName', 'department', 'teacherId', 'credit', 'courseType', 'location',
                       'time']
    for field in required_fields:
        if not data.get(field):
            return jsonify({
                'success': False,
                'message': f'缺少必填字段: {field}'
            }), 400

    # 验证教师是否存在
    teacher_id = int(data['teacherId'])
    teacher = Teacher.query.get(teacher_id)
    if not teacher:
        return jsonify({
            'success': False,
            'message': '指定的教师不存在'
        }), 400

    # 验证课程代码唯一性
    if Course.query.filter_by(course_code=data['courseCode']).first():
        return jsonify({
            'success': False,
            'message': '课程代码已存在'
        }), 400

    # 解析日期时间
    try:
        time_str = data['time']
        course_time = datetime.fromisoformat(time_str)
    except ValueError:
        return jsonify({
            'success': False,
            'message': '日期格式不正确，请使用YYYY-MM-DDTHH:MM格式'
        }), 400

    # 创建新课程
    new_course = Course(
        course_code=data['courseCode'],
        course_name=data['courseName'],
        credit=int(data['credit']),
        course_type=data['courseType'],
        department=data['department'],
        teacher_id=teacher_id,
        location=data['location'],
        time=course_time,
        description=data.get('description', '')
    )

    db.session.add(new_course)
    db.session.commit()

    return jsonify({
        'success': True,
        'message': '课程创建成功',
        'course': {
            'id': new_course.id,
            'course_code': new_course.course_code,
            'course_name': new_course.course_name,
            'teacher_name': teacher.username
        }
    })


# courses.py
@admin_bp.route('/course/get_teachers', methods=['GET'])
def get_teachers():
    """获取所有教师列表（用于下拉框）"""
    teachers = Teacher.query.all()
    # print(teachers)
    # 转换为前端可用的格式
    teacher_list = [{
        'id': teacher.id,
        'username': teacher.username,
        'teacher_no':teacher.teacher_no,
        'department': teacher.department
    } for teacher in teachers]

    return jsonify({
        'success': True,
        'teachers': teacher_list
    })


@admin_bp.route('/course/delete_course/<int:id>', methods=['DELETE'])
def delete_course(id):
    """删除课程（支持软删除和硬删除）"""
    # 查询课程是否存在
    course = Course.query.get_or_404(id)
    try:
        db.session.delete(course)
        db.session.commit()
        return jsonify({
            'success': True,
            'message': '课程删除成功'
        })

    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': '删除失败，请重试',
            'error': str(e)
        }), 500


@admin_bp.route('/course/search-course',methods=['GET'])
def course_search():
    """课程搜索接口 - 支持按课程编号和名称搜索"""
    # 获取搜索关键词并去除前后空格
    keyword = request.args.get('keyword', '').strip()
    # 构建基础查询
    query = Course.query
    # 添加搜索条件（支持按课程编号或名称搜索）
    if keyword:
        search_conditions = [
            Course.course_code.ilike(f'%{keyword}%'),  # 课程编号模糊匹配
            Course.course_name.ilike(f'%{keyword}%')  # 课程名称模糊匹配
        ]
        query = query.filter(or_(*search_conditions))

    # 执行查询并获取所有结果（不分页）
    courses = query.order_by(Course.id.desc()).all()

    # 计算搜索结果数量
    result_count = len(courses)

    # 渲染模板并返回
    return render_template('admin/course_admin.html',
                           courses=courses,
                           search_keyword=keyword,
                           result_count=result_count)


@admin_bp.route('/course/get-course/<int:id>', methods=['GET'])
def get_course_detail(id):
    """获取课程详情（用于编辑）"""
    course = Course.query.get_or_404(id)
    # 序列化课程数据（包含教师信息）
    course_data = {
        'id': course.id,
        'course_code': course.course_code,
        'course_name': course.course_name,
        'department': course.department,
        'teacher_id': course.teacher_id,
        'credit': course.credit,
        'course_type': course.course_type,
        'location': course.location,
        'time': course.time.isoformat(),  # 转换为ISO格式日期
        'description': course.description,
        'teacher_name': course.teacher.username  # 可选：传递教师姓名用于显示
    }

    return jsonify({
        'success': True,
        'data': course_data
    })

@admin_bp.route('/course/update-course/<int:id>', methods=['PUT'])
def update_course(id):
    """更新课程信息"""
    # 获取课程记录
    course = Course.query.get_or_404(id)
    # 获取表单数据
    data = request.form
    # print(data['courseName'])
    # 验证教师ID是否有效
    teacher = Teacher.query.get(data.get('teacherId'))
    # print(teacher)
    if not teacher:
        return jsonify({
            'success': False,
            'message': '无效的教师ID'
        }), 400
    # 更新课程字段
    course.course_code = data['courseCode']
    course.course_name = data['courseName']
    course.department = data['department']
    course.teacher_id = data['teacherId']
    course.credit = data['credit']
    course.course_type = data['courseType']
    course.location = data['location']
    course.time = datetime.fromisoformat(data['time'])
    course.description = data.get('description', '')
    course.updated_at = datetime.now()
    teacher = Teacher.query.get(data['teacherId'])

    # try:
        # 执行更新
    db.session.commit()
        # 返回更新后的课程数据
    return jsonify({
            'success': True,
            'message': '课程更新成功',
            'course': {
                'id': course.id,
                'course_code': course.course_code,
                'course_name': course.course_name,
                'department': course.department,
                'teacher_id': course.teacher_id,
                'teacher_name': teacher.username,
                'credit': course.credit,
                'course_type': course.course_type,
                'location': course.location,
                'time': course.time.isoformat(),
                'description': course.description,
                'updated_at': course.updated_at.isoformat()
            }
        })


@admin_bp.route('/class',methods=['GET','POST'])
def class_manage():
    class_list=Classes.query.all()
    return render_template('admin/class_admin.html',classes=class_list)

@admin_bp.route('/class/add_class', methods=['POST'])
def create_class():
    data = request.form
    # 验证必填字段
    class_name = data.get('class_name')
    major = data.get('major')
    grade = data.get('grade')
    advisor_id = data.get('advisor_id')
    if not all([class_name, major, grade, advisor_id]):
        return jsonify({'success': False, 'message': '缺少必要字段'}), 400
    # 验证年级和教师ID
    try:
        advisor_id = int(advisor_id)
    except ValueError:
        return jsonify({'success': False, 'message': '年级和教师ID必须为整数'}), 400

    # 验证教师是否存在
    teacher = Teacher.query.get(advisor_id)
    if not teacher:
        return jsonify({'success': False, 'message': '无效的教师ID'}), 400

    # 验证班级名称是否已存在
    if Classes.query.filter_by(class_name=class_name).first():
        return jsonify({'success': False, 'message': '班级名称已存在'}), 400
    # 处理可选字段
    monitor_id = data.get('monitor_id')
    if monitor_id=='':
        monitor_id=None
    description = data.get('description', '')
    # 创建班级
    new_class = Classes(
        class_name=class_name,
        major=major,
        grade=grade,
        advisor_id=advisor_id,
        monitor_id=monitor_id,
        description=description
    )
    db.session.add(new_class)
    db.session.commit()
    return jsonify({
        'success': True,
        'message': '班级创建成功',
        'class': {
            'id': new_class.id,
            'class_name': new_class.class_name,
            'major': new_class.major,
            'grade': new_class.grade,
            'advisor_id': new_class.advisor_id,
            'monitor_id': new_class.monitor_id,
            'description': new_class.description
        }
    }), 201

@admin_bp.route('/class/get_students/<int:id>', methods=['GET','POST'])
def get_students(id):
    class_name = Classes.query.get(id)
    students=class_name.students
    return jsonify({
        'success': True,
        'students': students
    })



@admin_bp.route('/class/update_class/<int:id>', methods=['PUT'])
def update_class(id):
    """更新班级信息"""
    # 获取班级记录
    class_obj = Classes.query.get_or_404(id)
    data = request.form
    # 验证必填字段
    class_name = data.get('class_name')
    major = data.get('major')
    grade = data.get('grade')
    advisor_id = data.get('advisor_id')
    if not all([class_name, major, grade, advisor_id]):
        return jsonify({'success': False, 'message': '缺少必要字段'}), 400
    # 验证年级和教师ID
    try:
        grade = int(grade)
        advisor_id = int(advisor_id)
    except ValueError:
        return jsonify({'success': False, 'message': '年级和教师ID必须为整数'}), 400
    # 验证教师是否存在
    teacher = Teacher.query.get(advisor_id)
    if not teacher:
        return jsonify({'success': False, 'message': '无效的教师ID'}), 400
    # 验证班级名称是否已存在（排除当前班级）
    existing_class = Classes.query.filter_by(class_name=class_name).first()
    if existing_class and existing_class.id != id:
        return jsonify({'success': False, 'message': '班级名称已存在'}), 400
    # 处理可选字段
    monitor_id = data.get('monitor_id')
    if monitor_id:
        try:
            monitor_id = int(monitor_id)
            # 验证学生是否存在
            if not Student.query.get(monitor_id):
                return jsonify({'success': False, 'message': '无效的学生ID（班长）'}), 400
        except ValueError:
            monitor_id = None
    else:
        monitor_id = None
    description = data.get('description', '')
    # 更新班级信息
    class_obj.class_name = class_name
    class_obj.major = major
    class_obj.grade = grade
    class_obj.advisor_id = advisor_id
    class_obj.monitor_id = monitor_id
    class_obj.description = description
    db.session.commit()
    return jsonify({
        'success': True,
        'message': '班级更新成功',
        'class': {
            'id': class_obj.id,
            'class_name': class_obj.class_name,
            'major': class_obj.major,
            'grade': class_obj.grade,
            'advisor_id': class_obj.advisor_id,
            'monitor_id': class_obj.monitor_id,
            'description': class_obj.description,
            'advisor_name': teacher.username if teacher else None,
            'monitor_name': class_obj.monitor.username if class_obj.monitor else None
        }
    })


@admin_bp.route('/class/<int:id>', methods=['DELETE'])
def delete_class(id):
    """删除班级"""
    class_obj = Classes.query.get_or_404(id)

    try:
        db.session.delete(class_obj)
        db.session.commit()
        return jsonify({'success': True, 'message': '班级删除成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': '删除失败：' + str(e)}), 500


@admin_bp.route('/class/get_class/<int:id>', methods=['GET'])
def get_class(id):
    """获取班级详情"""
    class_obj = Classes.query.get_or_404(id)
    return jsonify({
        'success': True,
        'class': {
            'id': class_obj.id,
            'class_name': class_obj.class_name,
            'major': class_obj.major,
            'grade': class_obj.grade,
            'advisor_id': class_obj.advisor_id,
            'monitor_id': class_obj.monitor_id,
            'description': class_obj.description,
            'advisor_name': class_obj.advisor.username if class_obj.advisor else None,
            'monitor_name': class_obj.monitor.username if class_obj.monitor else None
        }
    })


@admin_bp.route('/class/search', methods=['GET'])
def search_classes():
    keyword = request.args.get('keyword', '').strip()
    classes = Classes.query.filter(
        or_(
            Classes.class_name.like(f'%{keyword}%'),
            Classes.id.cast(db.String).like(f'%{keyword}%')
        )
    ).order_by(Classes.id.desc()).all()
    print(classes)
    return render_template('admin/class_admin.html', classes=classes, search_keyword=keyword)



